
package de.lmu.mvs.lerngruppenfinder;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.json.JSONException;
import org.json.JSONObject;

import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.eclipsesource.json.JsonValue;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

import de.lmu.mvs.lerngruppenfinder.R.id;
import de.lmu.mvs.lerngruppenfinder.interests.InterestNode;
import de.lmu.mvs.lerngruppenfinder.interests.InterestTree;
import de.lmu.mvs.lerngruppenfinder.utils.Constants;
import de.lmu.mvs.lerngruppenfinder.utils.FileApi;
import de.lmu.mvs.lerngruppenfinder.utils.ServerConnector;
import de.lmu.mvs.lerngruppenfinder.utils.ServerConnector.ServerConnectorListener;
import de.lmu.mvs.lerngruppenfinder.utils.Utils;
import de.lmu.mvs.lerngruppenfinder.utils.ServerConnector.ServerError;
import de.lmu.mvs.lerngruppenfinder.widget.ExpandablePanel;
import android.os.Build;
import android.os.Bundle;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import com.beardedhen.androidbootstrap.BootstrapButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class GroupDetailActivity extends FragmentActivity {
	
	private static final String TAG = GroupDetailActivity.class.getSimpleName();
	
	boolean ready;
	private int eventID;
	private TextView groupTitle;
	private TextView groupDate;
	private TextView groupInterest;
	private TextView groupDescription;
	private TextView groupParticipantsTitle;
	private TextView groupComments;
	private InterestTree mInterestTree;
	private LinearLayout mPartizipantsContainer;
	
	private GoogleMap mMap;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		if(Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB){
			getActionBar().setDisplayHomeAsUpEnabled(true);
		}
		
		setContentView(R.layout.activity_group_detail);
		
		groupTitle = (TextView) findViewById(R.id.group_title);
		groupDate = (TextView) findViewById(R.id.group_date);
		groupDescription = (TextView) findViewById(R.id.group_description);
		groupInterest = (TextView) findViewById(R.id.group_interest);
		groupParticipantsTitle = (TextView) findViewById(R.id.group_participants_title);
		groupComments = (TextView) findViewById(R.id.group_comments);
		mPartizipantsContainer = (LinearLayout) findViewById(id.value);
		
		mMap = ((SupportMapFragment) getSupportFragmentManager()
				.findFragmentById(R.id.map)).getMap();

		if(mMap != null){
			mMap.getUiSettings().setCompassEnabled(false);
			mMap.getUiSettings().setZoomControlsEnabled(false);
			mMap.getUiSettings().setMyLocationButtonEnabled(false);
			mMap.setMyLocationEnabled(false);
			mMap.getUiSettings().setAllGesturesEnabled(false);
		}
		
		Intent groupIntent = getIntent();
		if(groupIntent != null){
			int groupId = groupIntent.getIntExtra("id", 0);
			
			if(groupId > 0){
				loadGroupDetails(groupId);
				eventID=groupId;
			}
			else{
				eventID=Integer.parseInt(FileApi.readJsonFromStorage("actualEvent", GroupDetailActivity.this).asObject().get(Constants.JSON_ID).asString());
				populateView(FileApi.readJsonFromStorage("actualEvent", GroupDetailActivity.this));
			}
		}
		else{
			eventID=Integer.parseInt(FileApi.readJsonFromStorage("actualEvent", GroupDetailActivity.this).asObject().get(Constants.JSON_ID).asString());
			populateView(FileApi.readJsonFromStorage("actualEvent", GroupDetailActivity.this));
		}
		
		BootstrapButton abo = (BootstrapButton) findViewById(R.id.abo);
		BootstrapButton checkin = (BootstrapButton) findViewById(R.id.checkin);
		abo.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				ServerConnector.subscribeToGroup(new ServerConnectorListener<JsonObject>() {

					@Override
					public void requestError(ServerError error) {
						Log.w(CONNECTIVITY_SERVICE, error.getErrorMessage());
						Toast.makeText(getBaseContext(), error.getErrorMessage(), Toast.LENGTH_SHORT).show();

					}

					@Override
					public void requestFinished(JsonObject json) {
						Toast.makeText(getBaseContext(), "Erfolgreich aboniert", Toast.LENGTH_SHORT).show();;
						
					}
				}, FileApi.readLoginCredentials().id, eventID);
			}
		});		
		checkin.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				ServerConnector.checkinToEvent(new ServerConnectorListener<JsonObject>() {

					@Override
					public void requestFinished(JsonObject json) {
						Toast.makeText(getBaseContext(), "Erfolgreich eingecheckt", Toast.LENGTH_SHORT).show();
						
					}

					@Override
					public void requestError(ServerError error) {
						Log.w(CONNECTIVITY_SERVICE, error.getErrorMessage());
						Toast.makeText(getBaseContext(), error.getErrorMessage(), Toast.LENGTH_SHORT).show();

						
					}
				}, eventID, FileApi.readLoginCredentials().id);
			}
		});
		
	}

	private void loadGroupDetails(int groupId) {
		JsonValue json = FileApi.readJsonFromStorage("groups", this);
		
		if(json != null && json.isArray()){
			Log.d(TAG, "Found groups in storage. Process...");
			
			for (JsonValue group : json.asArray()) {
				try {
					int id = Integer.parseInt(group.asObject().get(Constants.JSON_ID).asString());
					if(id == groupId){
						populateView(group);
						break;
					}
				} catch(NumberFormatException e){
					continue;
				}
			}
		} else {
			Log.d(TAG, "Found no groups in storage. Try loading from url...");
			
			ServerConnector.getGroupById(new ServerConnectorListener<JsonObject>() {

				@Override
				public void requestFinished(JsonObject json) {
					Log.d(TAG, "Group loaded from url...");
					populateView(json);
				}

				@Override
				public void requestError(ServerError error) {
					Log.e(TAG, error.getErrorMessage());
				}
			
			}, groupId);
		}
	}
	
	private void populateView(JsonValue group){
		try {
			String interestID = group.asObject().get(Constants.JSON_INTEREST).asString();
			String name = group.asObject().get(Constants.JSON_GROUP_NAME).asString();
			String description = group.asObject().get(Constants.JSON_GROUP_DESCRIPTION).asString();
			double latitude = Double.parseDouble(group.asObject().get(Constants.JSON_LATITUDE).asString());
			double longitude = Double.parseDouble(group.asObject().get(Constants.JSON_LONGITUDE).asString());
			
			// load interest tree to display group interest
			JsonValue interestJson;
			Log.i(TAG, "Try loading interests from storage...");
			if((interestJson = FileApi.readJsonFromStorage("interests", this)) != null){
				if(interestJson.isArray()){
					mInterestTree = new InterestTree(interestJson.asArray());
					
					InterestNode node = mInterestTree.find(Integer.parseInt(interestID));
					InterestNode parentNode = node.getParent();
					
					groupInterest.setText( node.getInterestName() );
				}
			} else {
				Log.d(TAG, "Found no interests in storage. Try loading from url...");
				
				ServerConnector.getInterests(new ServerConnectorListener<JsonArray>() {

					@Override
					public void requestFinished(JsonArray json) {
						try {
							FileApi.writeJsonToStorage(json, "interests", GroupDetailActivity.this);
						} catch (IOException e) {
							e.printStackTrace();
						}
					}

					@Override
					public void requestError(ServerError error) {
						Log.e(TAG, error.getErrorMessage());
					}
					
				});
			}
			
			
			DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
			DateTime date = formatter.parseDateTime(group.asObject().get(Constants.JSON_GROUP_DATE).asString());
			
			groupTitle.setText(name);
			groupDate.setText(Utils.formatTime(date.getMillis()));
			groupDescription.setText(description);
			
			String tmp = group.asObject().get(Constants.JSON_ID).asString();
			int eventId = Integer.parseInt(tmp);

			// Get checked in users from server
			ServerConnector.getUsersCheckedIn(new ServerConnectorListener<JsonArray>() {

				@Override
				public void requestFinished(JsonArray json) {
					int participants = json.asArray().size();
					Log.i(TAG, "Teilnehmer Anzahl: " + String.valueOf(participants));
					
					// Anzahl der eingecheckten Teilnehmer ausgeben
					groupParticipantsTitle.setText("Teilnehmer: ( " + String.valueOf(participants) + " )");
					
					populateParticipants(json);
				}

				@Override
				public void requestError(ServerError error) {
					populateParticipants();
				}
				
			}, eventId);
			
			if(mMap != null){
				CameraPosition cameraPosition = new CameraPosition.Builder()
					.target(new LatLng(latitude, longitude))   
					.zoom(Constants.DETAIL_MAP_ZOOM).tilt(Constants.MAP_CAMERA_TILT).build();
				mMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
				
				mMap.addMarker(
						new MarkerOptions()
						.position(new LatLng(latitude, longitude))
						.title(name)
						.snippet(description));
			}
			
			ServerConnector.getComments(new ServerConnectorListener<JsonArray>() {

				@Override
				public void requestFinished(JsonArray json) {
					
					setOnClickListenerCommentsActivity(json);
				}
	
				@Override
				public void requestError(ServerError error) {
					Log.e(TAG, error.getErrorMessage());
				}
			
			}, eventId);
			
		} catch(IllegalArgumentException e){
			Log.e(TAG, "Error parsing group json.");
			e.printStackTrace();
		} catch(NullPointerException e){
			Log.e(TAG, "Error parsing group json.");
			e.printStackTrace();
		}
		
	}

	public void populateParticipants(JsonArray json) {
		
		// get usernames and id from json
		for (int i = 0; i < json.asArray().size(); i++) {
			String tempName = json.asArray().get(i).asObject().get("name").asString();
			final String tempUserID = json.asArray().get(i).asObject().get("userID").asString();
			
			// create views
			TextView tv = new TextView(this);
			tv.setText("  "+ tempName);
			
			// ausgewählten User anzeigen
			tv.setOnClickListener(new OnClickListener() {
							
				@Override
				public void onClick(View v) {
					Intent i = new Intent(getBaseContext(), ShowUserProfileActivity.class);
					i.putExtra("id", Integer.parseInt(tempUserID));
					startActivity(i);
				}
							
			});
						
			mPartizipantsContainer.addView(tv);
		}
	}
	
	public void populateParticipants() {

		TextView tv = new TextView(this);
		tv.setText(" > aktuell keine Teilnehmer");
		mPartizipantsContainer.addView(tv);
		
	}
	
	public void setOnClickListenerCommentsActivity(JsonArray json) {
		
		int comments = json.asArray().size();
		Log.i(TAG, "Kommentare Anzahl: " + String.valueOf(comments));
		
		// Anzahl der Kommentare ausgeben
		groupComments.setText("Kommentare: ( " + String.valueOf(comments) + " )");
		
		
		groupComments.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Intent i = new Intent(getBaseContext(), CommentsActivity.class);
				i.putExtra("id", eventID);
				startActivity(i);
			}
			
		});
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.group_detail, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
	    switch (item.getItemId()) {
	        case android.R.id.home:
	        	onBackPressed();
	            return true;
	        default:
	            return super.onOptionsItemSelected(item);
	    }
	}
}

